<!DOCTYPE html>
<html>

<head>
    <title>网络汇总</title>
    <style>
        .red {
          color: red;
        }
      </style>
</head>

<body>
    <h1>网络汇总</h1>


    <!-- <label for="networkAddress">网络地址:</label>
    <input type="text" id="networkAddress" value="192.168.1.0"><br>

    <label for="subnetMaskBits">子网掩码位数:</label>
    <input type="number" id="subnetMaskBits" value="27"><br> -->


    
  <label for="mask">子网掩码位数:</label>
  <input type="number" id="mask" value="24"><br>

  <label for="ipAddresses">IP 地址:</label>
  <textarea id="ipAddresses" rows="4" cols="50">192.168.1.0
192.168.3.0
192.168.5.0</textarea><br>

  <button onclick="summarizeNetworksDo()">计算</button>



    <!-- <button onclick="calculateNetworkSegments()">计算</button> -->

    <div id="result"></div>

    <script>
        function getIpFront3(parts) {
            let res = ""
            for (let i = 0; i < 3; i++) {
                res += parts[i] + "."
            }
            return res
        }

        function calculateNetworkSegments() {

            const networkAddress = document.getElementById("networkAddress").value;
            const subnetMaskBits = parseInt(document.getElementById("subnetMaskBits").value);

            // const networkAddress = "192.168.1.0";
            // const subnetMaskBits = 27;
            let jie = subnetMaskBits - 24
            let parts = networkAddress.split(".")
            //    for(let )
            let IpFront3 =
                getIpFront3(parts)
            let hostCnt = Math.pow(2, 8 - jie)
            console.log(`子网数2^jie=  2^${jie}= ${Math.pow(2,jie)}  主机容量=2^(8-jie) =2^(8-${jie}) =2^5=${hostCnt}`);
            const totalSubnets = Math.pow(2, subnetMaskBits - 24);
            const hostsPerSubnet = Math.pow(2, 32 - subnetMaskBits);
            let result = "<h2>网络划分详情</h2>";
            let resultDom = document.getElementById("result")
            resultDom.innerHTML +=
                `子网数2^jie=  2^${jie}= ${Math.pow(2,jie)}  主机容量=2^(8-jie) =2^(8-${jie}) =2^5=${Math.pow(2,8-jie)}\n`

            //   https://blog.csdn.net/LiuHuan303/article/details/119328221
            // let  networkAddressNow=
            let networkAddressLastNow = 0
            // 网络号和广播地址分别是：
            resultDom.innerHTML += `<p>网络号和广播地址分别是：</p>\n`
            for (let i = 0; i < totalSubnets; i++) {
                const subnetStart = i * hostsPerSubnet;
                const subnetEnd = subnetStart + hostsPerSubnet - 1;
                // const network = `${IpFront3}.${networkAddressLastNow}/${subnetMaskBits}`;
                const network = `${IpFront3}${networkAddressLastNow}/${subnetMaskBits}`;

                networkAddressLastNow += hostCnt
                // const network = `${networkAddress}/${subnetMaskBits}`;
                // const broadcast = `${subnetEndToIpAddress(subnetEnd)}/${subnetMaskBits}`;
                const broadcast = `${IpFront3}${networkAddressLastNow-1}/${subnetMaskBits}`;

                result += `<p>${network} ---- ${broadcast}</p>`;
            }

            //   document.getElementById("result").innerHTML = result;
            resultDom.innerHTML += result + "\n"
        }


        let resultDom = document.getElementById("result")
        function subnetEndToIpAddress(end) {
            const octets = [];
            for (let i = 3; i >= 0; i--) {
                const octet = Math.floor(end / Math.pow(256, i));
                octets.push(octet);
                end = end % Math.pow(256, i);
            }
            return octets.join(".");
        }

        // calculateNetworkSegments();

        function subFrontIp(binaryIP,mask){
            // for(let i=0)

           return   binaryIP.substr(0,mask)
        }

        function highLightItem(lst, index){

            // for(let i=0;i<lst.length;i++){
            //     if(i==index){
            //         lst[i].style.backgroundColor="red"
            //     }else{
            //         lst[i].style.backgroundColor="white"
            //     }
            // }

            let  res=""
            for(let i=0;i<lst.length;i++){
                if(i==index){
                    res+=`(${lst[i]})`
                    // lst[i].style.backgroundColor="red"
                }else{
                    res+= `${lst[i]}`
                    // lst[i].style.backgroundColor="white"
                }
            }
            return res
        }

        function markStringRed(inputString,n){
            const markedString = `<p>
                </span><span class="red">${inputString.slice(0, n)}</span>${inputString.slice(n)}  </p>`;

            return markedString
        }


        function listDisplayStr(lst){

            let res=""
            for(let o of lst){
                // res+=o+"\n"
                res+= `<p>${o}</p>\n`
            }
            return res
        }


        function  summarizeNetworksDo(){
            resultDom.innerHTML=""
            const mask = parseInt(document.getElementById("mask").value);
      const ipAddresses = document.getElementById("ipAddresses").value.split("\n").map(ip => ip.trim()).filter(ip => ip !== "");
   const summary=  summarizeNetworks(ipAddresses,mask)
      resultDom.innerHTML+=`<p>summary ${summary}</p>\n`
        }

        function summarizeNetworks(ipAddresses,mask) {

      

            // 将 IP 地址转换为二进制表示形式的数组
            const binaryIPs = ipAddresses.map(ip => ipToBinary(ip));
            resultDom.innerHTML += "<p> 将 IP 地址转换为二进制表示形式的数组</p>\n"
            let   binaryIPsDisplay= listDisplayStr(binaryIPs)
            resultDom.innerHTML += `<p> binaryIPs </p>\n`
            resultDom.innerHTML += `${binaryIPsDisplay}\n`
            console.log("binaryIPs");
            console.log(binaryIPs);
            let  binaryIP0=binaryIPs[0]
           
            console.log("binaryIP0");
            console.log(binaryIP0);
         let subFrontIp0=    subFrontIp(binaryIPs[0],mask)
         console.log("subFrontIp0");
            console.log(subFrontIp0);
            // 找到不相同位置的索引
            resultDom.innerHTML += " <p>找到不相同位置的索引</p>\n"
            let index = 0;
            while (index < binaryIPs[0].length && allBitsEqual(binaryIPs, index)) {
                index++;
            }
            // let  highLightItemIpList=  binaryIPs.map(ip => highLightItem(ip,index-1));
            let  highLightItemIpList=  binaryIPs.map(ip => markStringRed(ip,index));

            // let  highLightItemIpList=  binaryIPs.map(ip => markStringRed(ip,index-1));

        //   let  highLightItemIpList=  binaryIPs.map(ip => highLightItem(ip,index));
          console.log("highLightItemIpList");
           console.log(highLightItemIpList);
        //    let  highLightItemIp0Str=  highLightItem(binaryIP0,index)
        //    console.log("highLightItemIp0Str");
        //    console.log(highLightItemIp0Str);
        // js 给字符串的 前面n个 红色 

     let   highLightItemIpListDisplayStr= listDisplayStr(highLightItemIpList)
    //  highLightItemIpListDisplayStr
        // resultDom.innerHTML +=  ` <p>highLightItemIpList ${highLightItemIpList}</p>\n`
        resultDom.innerHTML +=  ` <p>红色的 到此为止都对上了 </p>\n`
        resultDom.innerHTML +=  ` <p>${highLightItemIpListDisplayStr} </p>\n`

            resultDom.innerHTML += ` <p>index ${index}</p>\n`


            // 构建网络汇总的网段
            const networkAddress = binaryIPs[0].slice(0, index) + "0".repeat(32 - index);
            const subnetMaskBits = index;
          
            // 返回网段表示
            return `${binaryToIP(networkAddress)}/${subnetMaskBits}`;
        }

        // 辅助函数：将 IP 地址转换为二进制表示形式
        function ipToBinary(ip) {
            return ip.split(".").map(part => parseInt(part).toString(2).padStart(8, "0")).join("");
        }

        // 辅助函数：检查给定索引位置的比特是否在所有 IP 地址中都相等
        function allBitsEqual(binaryIPs, index) {
            const bit = binaryIPs[0][index];
            for (let i = 1; i < binaryIPs.length; i++) {
                if (binaryIPs[i][index] !== bit) {
                    return false;
                }
            }
            return true;
        }

        // 辅助函数：将二进制表示形式的 IP 地址转换为常规表示形式
        function binaryToIP(binaryIP) {
            const octets = [];
            for (let i = 0; i < 32; i += 8) {
                const octet = parseInt(binaryIP.slice(i, i + 8), 2);
                octets.push(octet);
            }
            return octets.join(".");
        }

        let mask=24
        // 测试
        const ipAddresses = ["192.168.1.0", "192.168.3.0", "192.168.5.0"];
        // const summary = summarizeNetworks(ipAddresses,mask);
        // console.log("summary"); // 输出: 192.168.0.0/21
        // console.log(summary);
        // resultDom.innerHTML+=`<p>summary ${summary}</p>\n`
    </script>
</body>

</html>